package org.ccay.core.base;

import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;

import org.ccay.core.log.CcayLoggerFactory;
import org.ccay.core.log.ILogger;
import org.ccay.core.util.CollectionUtil;
import org.ccay.core.util.JsonUtil;
import org.ccay.core.util.PatternUtil;
import org.ccay.core.util.StringUtil;
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
import org.codehaus.jackson.type.TypeReference;
/**
 * 分页VO
 * 
 * @since 2011-8-25
 */
@XmlRootElement
@JsonIgnoreProperties(ignoreUnknown=true,value={"filters"})
public final class PageVO implements Serializable{
	
	private static final long serialVersionUID = 1112199160788845959L;
	
	private static ILogger log = CcayLoggerFactory.getLogger(PageVO.class);
	
	/**
	 * 总的行数
	 */
	private int totalRows;
	/**
	 * 当前页
	 */
	private int curPage = 1;
	/**
	 * 每页条数，默认15
	 */
	private int pageSize = PageConfig.DEFAULT.getDefaultPageSize();
	/**
	 * 结果模式，配合PageInterceptor使用，为0或未赋值时同时取结果集与记录总数，为1时只取记录总数，为2时只取结果集
	 */
	private int resultMode;
	/**
	 * 分页表达式
	 */
	private String orderBy; 
	
	private String filterStr; 
	
	private List<FilterVO> filters = new ArrayList<FilterVO>();
	
	/**
	 * 起始位置(mysql 0开始算 oracel 1开始算) 
	 */
	private boolean indexBaseZero = true;

	/**
	 * 在mysql中limit由0开始算，但在oracel中rownum是由1开始计算
	 * 默认由0开始计算
	 * @param startIndexBaseZero
	 */
	public void setIndexBaseZero(boolean indexBaseZero) {
		this.indexBaseZero = indexBaseZero;
	}
	
	private int startIndex, endIndex;

	/**
	 * @return startIndex
	 */
	public int getStartIndex(){
		int offset = indexBaseZero ? 0 : 1;
		return this.startIndex == 0 ? (this.curPage - 1) * this.pageSize + offset : this.startIndex;
	}
	
	/** 
	 * 设置startIndex，用于滚动分页
	 * @param startIndex
	 */
	@XmlTransient 
	public void setStartIndex(int startIndex){
		this.startIndex = startIndex;
	}
 
	/**
	 * @return endIndex
	 */
	public int getEndIndex() {
		if(endIndex - startIndex > PageConfig.DEFAULT.getMaxPageSize()) {
			log.error("The endIndex param is too large, default page size will be used. You can modify the MaxPageSize use the following method: PageConfig.DEFAULT.setMaxPageSize() .");
			return startIndex + PageConfig.DEFAULT.getDefaultPageSize();
		}
//		return endIndex == 0 ? curPage*pageSize : endIndex;
		// 修复当endIndex大于totalRows时，查询出的数据错误的问题
		return endIndex == 0 ? curPage*pageSize : (endIndex - 1 > totalRows ? totalRows : endIndex);
	}
	
	/** 
	 * 设置endIndex，用于滚动分页
	 * @param endIndex
	 */
	@XmlTransient 
	public void setEndIndex(int endIndex){
		this.endIndex = endIndex;
	}
	
	/**
	 * @return totalRows
	 */
	public int getTotalRows() {
		return totalRows;
	}
	/**
	 * @param totalRows 要设置的 totalRows
	 */
	public void setTotalRows(int totalRows) {
		this.totalRows = totalRows;
	}
	/**
	 * @return curPage
	 */
	public int getCurPage() {
		return curPage;
	}
	/**
	 * @param curPage 要设置的 curPage
	 */
	public void setCurPage(int curPage) {
		this.curPage = curPage;
	}
	/**
	 * @return pageSize
	 */
	public int getPageSize() {
		return pageSize;
	}
	/**
	 * @param pageSize 要设置的 pageSize
	 */
	public void setPageSize(int pageSize) {
		if(pageSize <=0 || pageSize > PageConfig.DEFAULT.getMaxPageSize()) {
			log.error("The pageSize param is too large, default page size will be used. You can modify the MaxPageSize use the following method: PageConfig.DEFAULT.setMaxPageSize() ..");
			return;
		}
		this.pageSize = pageSize;
	}

	public int getResultMode() {
		return resultMode;
	}

	public void setResultMode(int resultMode) {
		this.resultMode = resultMode;
	}

	/**
	 * @return orderBy，需要进行安全性过滤
	 */
	public String getOrderBy() {
		return orderBy;
	}

	/**
	 * 设置Order by表达式，本方法会针对参数进行正则检验，仅允许字母、数字、空格、下划线、点、逗号这些字符，校验不通过时设置 orderBy 为"1"
	 * @param orderBy 要设置的 orderBy
	 */
	public void setOrderBy(String orderBy) {		
		if(! StringUtil.isNullOrEmpty(orderBy) && !PatternUtil.SQL_ORDER_BY.matcher(orderBy).matches()){
			log.warn("Dangerous order by pattern detected. It will be ignore ");
			this.orderBy = "1";	
			return ;
		}		
		
		this.orderBy = orderBy;
	}
	
	 
	/**
	 * @return
	 */
	public List<FilterVO> getFilters() {
		//如果filters为null 并且 filterstr不为空 那么再转换
		if(!CollectionUtil.isNullOrEmpty(filters) || StringUtil.isNullOrEmpty(getFilterStr())
				//只个判断是 代表前台没有传递筛选
				|| "[]".equals(getFilterStr())){
			return filters;
		}
		TypeReference<List<FilterVO>> type = new TypeReference<List<FilterVO>>(){};
		try {
			filters = JsonUtil.stringToObject(getFilterStr(), type);
		} catch (IOException e) {
			log.error(e);
		}
		return filters;
	}

	/**
	 * @param filters
	 */
	public void setFilters(List<FilterVO> filters) {
		
		this.filters = filters;
	}
	
	public String getFilterStr() {
		return filterStr;
	}

	public void setFilterStr(String filterStr) {
		this.filterStr = filterStr;
	}

	/**
	 * @return totalPages
	 */
	public int getTotalPages() {
		return  totalRows%pageSize == 0 ? totalRows/pageSize:totalRows/pageSize+1;
	}

}
